import ecdsa
import random
import codecs

_p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
_r =  0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
_b = 0x0000000000000000000000000000000000000000000000000000000000000007

_a = 0x0000000000000000000000000000000000000000000000000000000000000000
_GX =  0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
_GY = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8  ## NIST  算法 一大堆墨明棋妙的魔数，所以 最好用libsodium 替换掉 NIST ,但比特币用的是这个，所以 

curveScep256k1 = ecdsa.ellipticcurve.CurveFp(_p, _a, _b)
generaterScep256k1 = ecdsa.ellipticcurve.Point(curveScep256k1, _GX, _GY, _r)
oidSecp256k1 = (1,3,132,0,10)
SECP256K1 = ecdsa.curves.Curve("SECP256k1", curveScep256k1, generaterScep256k1, oidSecp256k1)

ecOrder = _r
generator = generaterScep256k1
curve = curveScep256k1

def randomSecret():
    randomChr = lambda: chr(random.randint(0, 255))
    convertToInt = lambda array: int(codecs.encode("".join(array)).hex(), 16)
    byteArray = [randomChr() for i in range(32)]
    return convertToInt(byteArray)

def getPointPubkey(point):
    if point.y() & 1:
        key = '03' + '%064x' % point.x() # 计数 03 开头 
    else:
        key = '02' + '%064x' % point.x() # 偶数02 开头
    return key

def getPointPubKeyUnCompressed(point):
    key = '04' + '%064x' % point.x() + '%064x' % point.y()
    return key
secret = randomSecret()
print("secret:", secret)
point = secret * generator
print("EC point:", point)

print("BTC public key:", getPointPubkey(point))
point1 = ecdsa.ellipticcurve.Point(curve, point.x(), point.y(), ecOrder)
assert(point1 == point)